#include "Solution.hh"


ArrayList<Objective> *Solution::objectives = NULL;

ArrayList<Restriction> *Solution::restrictions = NULL;

int Solution::hits = 0;

int Solution::evaluations = 0;


Solution::Solution(Solution &solution) {

    if (solution.objectivesValues != NULL) {
        objectivesValues = new double[Solution::objectives->length()];

        for (int i = 0; i < Solution::objectives->length(); i++)
            objectivesValues[i] = solution.objectivesValues[i];

    } else objectivesValues = NULL;

    fitness = solution.fitness;

    crowding = solution.crowding;

    changed = solution.changed;
}

double Solution::getObjectiveValue(int i) {
    return objectivesValues[i];
}


void Solution::evaluate() {

    evaluations++;

    if (!changed) {
        hits++;
        return ;
    }

    if (objectivesValues != NULL) delete [] objectivesValues;

    objectivesValues = new double[Solution::objectives->length()];

    for (int i = 0; i < Solution::objectives->length(); i++)
        objectivesValues[i] = objectives->get(i)->evaluate(this);

    changed = false;
}


bool Solution::dominates(Solution *solution) {

    if (solution->objectivesValues == NULL) solution->evaluate();

    if (objectivesValues == NULL) evaluate();

    int more = 0;

    int m = Solution::objectives->length();

    for (int i = 0; i < m; i++) {

        if (Solution::objectives->get(i)->getDirection() == MINIMIZE) {

            if (objectivesValues[i] <= solution->objectivesValues[i]) {

                if (objectivesValues[i] < solution->objectivesValues[i])
                    more++;

            } else return false;

        } else {

            if (objectivesValues[i] >= solution->objectivesValues[i]) {

                if (objectivesValues[i] > solution->objectivesValues[i])
                    more++;


            } else return false;
        }

    }

    if (more > 0) return true;

    else return false;
}

